package com.sevenluo.netty.learn.client;

import com.sevenluo.netty.learn.client.codec.*;
import com.sevenluo.netty.learn.client.handler.OperationResultFuture;
import com.sevenluo.netty.learn.client.handler.RequestPendingCenter;
import com.sevenluo.netty.learn.client.handler.ResponseDispatcherHandler;
import com.sevenluo.netty.learn.common.OperationResult;
import com.sevenluo.netty.learn.common.RequestMessage;
import com.sevenluo.netty.learn.common.order.OrderOperation;
import com.sevenluo.netty.learn.util.IdUtil;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;

import java.util.concurrent.ExecutionException;

/**
 * 响应分发客户端，可以实现响应消息的分发，拿到响应消息进行处理
 */
public class ClientV2 {

    public static void main(String[] args) throws InterruptedException, ExecutionException {

        NioEventLoopGroup group = new NioEventLoopGroup();
        try {
            RequestPendingCenter requestPendingCenter = new RequestPendingCenter();
            Bootstrap bootstrap = new Bootstrap();

            bootstrap.channel(NioSocketChannel.class)
                    .group(group)
                    .handler(new ChannelInitializer<NioSocketChannel>() {
                        @Override
                        protected void initChannel(NioSocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new OrderFrameDecoder());
                            pipeline.addLast(new OrderFrameEncoder());

                            pipeline.addLast(new OrderProtocolEncoder());
                            pipeline.addLast(new OrderProtocolDecoder());

                            pipeline.addLast(new ResponseDispatcherHandler(requestPendingCenter));

                            pipeline.addLast(new OperationToRequestMessageEncoder());

                            pipeline.addLast(new LoggingHandler(LogLevel.INFO));
                        }
                    });

            ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 8080).sync();

            long streamId = IdUtil.nextId();

            RequestMessage requestMessage = new RequestMessage(
                    streamId, new OrderOperation(1001, "tudou"));
            // 声明获取结果的 future
            OperationResultFuture operationResultFuture = new OperationResultFuture();
            // 添加到分发容器中
            requestPendingCenter.add(streamId, operationResultFuture);

            channelFuture.channel().writeAndFlush(requestMessage);
            // 阻塞等待响应消息
            OperationResult operationResult = operationResultFuture.get();

            System.out.println(operationResult);

            channelFuture.channel().closeFuture().sync();

        } finally {
            group.shutdownGracefully();
        }
    }

}
